home *** CD-ROM | disk | FTP | other *** search
/ Computer Inter@ctive 16 / Computer Interactive cdrom 16 - dic 98.iso / zdnetit / content / CLASSBLD.ZIP / Include / CB_ValueTree.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-06  |  18.0 KB  |  592 lines

  1. #ifndef CB_VALUETREE_H
  2. #define CB_VALUETREE_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "CB_IteratorMulti.h"
  7.  
  8. // defines for include files
  9. #define RELATION_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  10. private:\
  11.     ClassTo* _first##NameTo;\
  12.     int _count##NameTo;\
  13. \
  14. public:\
  15.     void Add##NameTo(ClassTo* item);\
  16.     void Remove##NameTo(ClassTo* item);\
  17.     void RemoveAll##NameTo();\
  18.     void DeleteAll##NameTo();\
  19.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  20.     ClassTo* GetFirst##NameTo();\
  21.     ClassTo* GetLast##NameTo();\
  22.     ClassTo* GetNext##NameTo(ClassTo* pos);\
  23.     ClassTo* GetPrev##NameTo(ClassTo* pos);\
  24.     int Get##NameTo##Count();\
  25.     ITERATOR_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  26.  
  27. #define RELATION_NOFILTER_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  28. private:\
  29.     ClassTo* _first##NameTo;\
  30.     int _count##NameTo;\
  31. \
  32. public:\
  33.     void Add##NameTo(ClassTo* item);\
  34.     void Remove##NameTo(ClassTo* item);\
  35.     void RemoveAll##NameTo();\
  36.     void DeleteAll##NameTo();\
  37.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  38.     ClassTo* GetFirst##NameTo();\
  39.     ClassTo* GetLast##NameTo();\
  40.     ClassTo* GetNext##NameTo(ClassTo* pos);\
  41.     ClassTo* GetPrev##NameTo(ClassTo* pos);\
  42.     int Get##NameTo##Count();\
  43.     ITERATOR_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  44.  
  45. #define RELATION_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  46. public:\
  47.     ClassFrom* _ref##NameFrom;\
  48.     ClassTo* _parent##NameFrom;\
  49.     ClassTo* _left##NameFrom;\
  50.     ClassTo* _right##NameFrom;\
  51.     ClassTo* _sibling##NameFrom;\
  52. \
  53. public:\
  54.     ClassFrom* Get##NameFrom() { return _ref##NameFrom; };
  55.  
  56. // defines implementation
  57. #define INIT_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  58.     _first##NameTo = (ClassTo*)0;\
  59.     _count##NameTo = 0;
  60.  
  61. #define EXIT_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  62.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  63.           Remove##NameTo(item); }
  64.  
  65. #define REPLACE_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  66.     _first##NameTo = pOld->_first##NameTo;\
  67.     _count##NameTo = pOld->_count##NameTo;\
  68.     pOld->_first##NameTo = (ClassTo*)0;\
  69.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  70.           item->_ref##NameFrom = this; }
  71.  
  72. #define INIT_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  73.     _ref##NameFrom = (ClassFrom*)0;\
  74.     _parent##NameFrom = (ClassTo*)0;\
  75.     _left##NameFrom = (ClassTo*)0;\
  76.     _right##NameFrom = (ClassTo*)0;\
  77.     _sibling##NameFrom = (ClassTo*)0;
  78.  
  79. #define EXIT_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  80.     if (_ref##NameFrom)\
  81.         _ref##NameFrom->Remove##NameTo(this);
  82.  
  83. #define REPLACE_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  84.     _ref##NameFrom = (ClassFrom*)0;\
  85.     _parent##NameFrom = (ClassTo*)0;\
  86.     _left##NameFrom = (ClassTo*)0;\
  87.     _right##NameFrom = (ClassTo*)0;\
  88.     _sibling##NameFrom = (ClassTo*)0;\
  89.     if (pOld->_ref##NameFrom)\
  90.         pOld->_ref##NameFrom->Replace##NameTo(pOld, this);
  91.  
  92. #define METHODS_VALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  93. void ClassFrom##::Add##NameTo(ClassTo* item)\
  94. {\
  95.     METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  96. }\
  97. \
  98. void ClassFrom##::Remove##NameTo(ClassTo* item)\
  99. {\
  100.     METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  101. }\
  102. \
  103. void ClassFrom##::RemoveAll##NameTo()\
  104. {\
  105.     METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  106. }\
  107. \
  108. void ClassFrom##::DeleteAll##NameTo()\
  109. {\
  110.     METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  111. }\
  112. \
  113. void ClassFrom##::Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  114. {\
  115.     METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  116. }\
  117. \
  118. ClassTo* ClassFrom##::GetFirst##NameTo()\
  119. {\
  120.     METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  121. }\
  122. \
  123. ClassTo* ClassFrom##::GetLast##NameTo()\
  124. {\
  125.     METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  126. }\
  127. \
  128. ClassTo* ClassFrom##::GetNext##NameTo(ClassTo* pos)\
  129. {\
  130.     METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  131. }\
  132. \
  133. ClassTo* ClassFrom##::GetPrev##NameTo(ClassTo* pos)\
  134. {\
  135.     METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  136. }\
  137. \
  138. int ClassFrom##::Get##NameTo##Count()\
  139. {\
  140.     METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  141. }
  142.  
  143. #define METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  144.     assert(this);\
  145. \
  146.     assert(item);\
  147.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  148. \
  149.     _count##NameTo++;\
  150. \
  151.     item->_ref##NameFrom = this;\
  152. \
  153.     if (_first##NameTo)\
  154.     {\
  155.         ClassTo* current = _first##NameTo;\
  156.         unsigned long bit = 0x1;\
  157.         while (1)\
  158.         {\
  159.             if(current->member != item->member)\
  160.             {\
  161.                 if ((current->member & bit) == (item->member & bit))\
  162.                 {\
  163.                     if (current->_left##NameFrom)\
  164.                     {\
  165.                         current = current->_left##NameFrom;\
  166.                     }\
  167.                     else\
  168.                     {\
  169.                         current->_left##NameFrom = item;\
  170.                         item->_parent##NameFrom = current;\
  171.                         break;\
  172.                     }\
  173.                 }\
  174.                 else\
  175.                 {\
  176.                     if (current->_right##NameFrom)\
  177.                     {\
  178.                         current = current->_right##NameFrom;\
  179.                     }\
  180.                     else\
  181.                     {\
  182.                         current->_right##NameFrom = item;\
  183.                         item->_parent##NameFrom = current;\
  184.                         break;\
  185.                     }\
  186.                 }\
  187. \
  188.                 bit <<= 1;\
  189.             }\
  190.             else\
  191.             {\
  192.                 item->_sibling##NameFrom = current->_sibling##NameFrom;\
  193.                 item->_parent##NameFrom = current;\
  194.                 current->_sibling##NameFrom = item;\
  195.                 if (item->_sibling##NameFrom)\
  196.                     item->_sibling##NameFrom->_parent##NameFrom = item;\
  197.                 break;\
  198.             }\
  199.         }\
  200.     }\
  201.     else\
  202.     {\
  203.         _first##NameTo = item;\
  204.     }
  205.  
  206. #define METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  207.     assert(this);\
  208. \
  209.     assert(item);\
  210.     assert(item->_ref##NameFrom == this);\
  211. \
  212.     ClassFrom##::##NameTo##Iterator::Check(item);\
  213. \
  214.     _count##NameTo--;\
  215. \
  216.     if (item->_parent##NameFrom && item->_parent##NameFrom->_sibling##NameFrom == item)\
  217.     {\
  218.         item->_parent##NameFrom->_sibling##NameFrom = item->_sibling##NameFrom;\
  219.         if (item->_sibling##NameFrom)\
  220.             item->_sibling##NameFrom->_parent##NameFrom = item->_parent##NameFrom;\
  221.     }\
  222.     else if (item->_sibling##NameFrom)\
  223.     {\
  224.         ClassTo* replacement = item->_sibling##NameFrom;\
  225.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  226.         replacement->_left##NameFrom = item->_left##NameFrom;\
  227.         if (item->_left##NameFrom)\
  228.             item->_left##NameFrom->_parent##NameFrom = replacement;\
  229.         replacement->_right##NameFrom = item->_right##NameFrom;\
  230.         if (item->_right##NameFrom)\
  231.             item->_right##NameFrom->_parent##NameFrom = replacement;\
  232. \
  233.         ClassTo* parent = item->_parent##NameFrom;\
  234.         if (parent)\
  235.         {\
  236.             if (parent->_left##NameFrom == item)\
  237.             {\
  238.                 parent->_left##NameFrom = replacement;\
  239.             }\
  240.             else\
  241.             {\
  242.                 parent->_right##NameFrom = replacement;\
  243.             }\
  244.         }\
  245.         else\
  246.         {\
  247.             _first##NameTo = replacement;\
  248.         }\
  249.     }\
  250.     else\
  251.     {\
  252.         ClassTo* replacement = 0;\
  253.         ClassTo* move = 0;\
  254.         if (item->_left##NameFrom)\
  255.         {\
  256.             replacement = item->_left##NameFrom;\
  257.             replacement->_parent##NameFrom = item->_parent##NameFrom;\
  258.             move = item->_right##NameFrom;\
  259.         }\
  260.         else if (item->_right##NameFrom)\
  261.         {\
  262.             replacement = item->_right##NameFrom;\
  263.             replacement->_parent##NameFrom = item->_parent##NameFrom;\
  264.         }\
  265.     \
  266.         ClassTo* parent = item->_parent##NameFrom;\
  267.         if (parent)\
  268.         {\
  269.             if (parent->_left##NameFrom == item)\
  270.             {\
  271.                 parent->_left##NameFrom = replacement;\
  272.             }\
  273.             else\
  274.             {\
  275.                 parent->_right##NameFrom = replacement;\
  276.             }\
  277.         }\
  278.         else\
  279.         {\
  280.             _first##NameTo = replacement;\
  281.         }\
  282.     \
  283.         if (replacement)\
  284.         {\
  285.             while (1)\
  286.             {\
  287.                 ClassTo* tmp = replacement->_right##NameFrom;\
  288.                 replacement->_right##NameFrom = move;\
  289.                 if (move)\
  290.                 {\
  291.                     move->_parent##NameFrom = replacement;\
  292.                 }\
  293.                 \
  294.                 if (!replacement->_left##NameFrom)\
  295.                 {\
  296.                     if (tmp)\
  297.                     {\
  298.                         replacement->_left##NameFrom = tmp;\
  299.                         tmp = 0;\
  300.                     }\
  301.                     else\
  302.                     {\
  303.                         break;\
  304.                     }\
  305.                 }\
  306.                 move = tmp;\
  307.                 replacement = replacement->_left##NameFrom;\
  308.             }\
  309.         }\
  310.     }\
  311. \
  312.     item->_ref##NameFrom = (ClassFrom*)0;\
  313.     item->_parent##NameFrom = (ClassTo*)0;\
  314.     item->_left##NameFrom = (ClassTo*)0;\
  315.     item->_right##NameFrom = (ClassTo*)0;\
  316.     item->_sibling##NameFrom = (ClassTo*)0;
  317.  
  318. #define METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  319.     assert(this);\
  320. \
  321.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  322.           Remove##NameTo(item);
  323.  
  324. #define METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  325.     assert(this);\
  326. \
  327.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  328.           delete item;
  329.  
  330. #define METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  331.     assert(this);\
  332. \
  333.     assert(item);\
  334.     assert(item->_ref##NameFrom == this);\
  335. \
  336.     assert(newItem);\
  337.     assert(newItem->_ref##NameFrom == (ClassFrom*)0);\
  338. \
  339.     if (item->member == newItem->member)\
  340.     {\
  341.         ClassFrom##::##NameTo##Iterator::Check(item, newItem);\
  342.         if (_first##NameTo == item)\
  343.         {\
  344.             _first##NameTo = newItem;\
  345.         }\
  346.         if (item->_parent##NameFrom)\
  347.         {\
  348.             if (item->_parent##NameFrom->_left##NameFrom == item)\
  349.             {\
  350.                 item->_parent##NameFrom->_left##NameFrom = newItem;\
  351.             }\
  352.             else if (item->_parent##NameFrom->_right##NameFrom == item)\
  353.             {\
  354.                 item->_parent##NameFrom->_right##NameFrom = newItem;\
  355.             }\
  356.             else if (item->_parent##NameFrom->_sibling##NameFrom == item)\
  357.             {\
  358.                 item->_parent##NameFrom->_sibling##NameFrom = newItem;\
  359.             }\
  360.         }\
  361.         newItem->_ref##NameFrom = this;\
  362.         newItem->_parent##NameFrom = item->_parent##NameFrom;\
  363.         newItem->_left##NameFrom = item->_left##NameFrom;\
  364.         newItem->_right##NameFrom = item->_right##NameFrom;\
  365.         newItem->_sibling##NameFrom = item->_sibling##NameFrom;\
  366.         item->_ref##NameFrom = (ClassFrom*)0;\
  367.         item->_parent##NameFrom = (ClassTo*)0;\
  368.         item->_left##NameFrom = (ClassTo*)0;\
  369.         item->_right##NameFrom = (ClassTo*)0;\
  370.         item->_sibling##NameFrom = (ClassTo*)0;\
  371.     }\
  372.     else\
  373.     {\
  374.         ClassFrom##::##NameTo##Iterator::Check(item);\
  375.         Remove##NameTo(item);\
  376.         Add##NameTo(newItem);\
  377.     }
  378.  
  379. #define METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  380.     assert(this);\
  381.     return _first##NameTo;
  382.  
  383. #define METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  384.     assert(this);\
  385. \
  386.     ClassTo* result = _first##NameTo;\
  387.     while (result)\
  388.     {\
  389.         while (result->_right##NameFrom)\
  390.         {\
  391.             result = result->_right##NameFrom;\
  392.         }\
  393. \
  394.         if (result->_left##NameFrom)\
  395.         {\
  396.             result = result->_left##NameFrom;\
  397.         }\
  398.         else\
  399.         {\
  400.             break;\
  401.         }\
  402.     }\
  403. \
  404.     if (result)\
  405.     {\
  406.         while (result->_sibling##NameFrom)\
  407.             result = result->_sibling##NameFrom;\
  408.     }\
  409. \
  410.     return result;
  411.  
  412. #define METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  413.     assert(this);\
  414. \
  415.     ClassTo* result = 0;\
  416.     if (pos == (ClassTo*)0)\
  417.         result = _first##NameTo;\
  418.     else\
  419.     {\
  420.         assert(pos->_ref##NameFrom == this);\
  421. \
  422.         if (pos->_sibling##NameFrom)\
  423.             result = pos->_sibling##NameFrom;\
  424.         else\
  425.         {\
  426.             while (pos->_parent##NameFrom && pos->_parent##NameFrom->_sibling##NameFrom == pos)\
  427.                 pos = pos->_parent##NameFrom;\
  428. \
  429.             if (pos->_left##NameFrom)\
  430.             {\
  431.                 result = pos->_left##NameFrom;\
  432.             }\
  433.             else\
  434.             {\
  435.                 if (pos->_right##NameFrom)\
  436.                 {\
  437.                     result = pos->_right##NameFrom;\
  438.                 }\
  439.                 else\
  440.                 {\
  441.                     ClassTo* parent = pos->_parent##NameFrom;\
  442.                     while (parent && (parent->_right##NameFrom == 0 || parent->_right##NameFrom == pos))\
  443.                     {\
  444.                         pos = parent;\
  445.                         parent = parent->_parent##NameFrom;\
  446.                     }\
  447. \
  448.                     if (parent)\
  449.                     {\
  450.                         result = parent->_right##NameFrom;\
  451.                     }\
  452.                 }\
  453.             }\
  454.         }\
  455.     }\
  456. \
  457.     return result;
  458.  
  459. #define METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  460.     assert(this);\
  461. \
  462.     ClassTo* result = 0;\
  463.     if (pos == (ClassTo*)0)\
  464.         result = GetLast##NameTo();\
  465.     else\
  466.     {\
  467.         assert(pos->_ref##NameFrom == this);\
  468. \
  469.         if (pos->_parent##NameFrom)\
  470.         {\
  471.             if (pos->_parent##NameFrom->_sibling##NameFrom == pos)\
  472.                 result = pos->_parent##NameFrom;\
  473.             else\
  474.             {\
  475.                 if (pos->_parent##NameFrom->_left##NameFrom == pos || pos->_parent##NameFrom->_left##NameFrom == 0)\
  476.                 {\
  477.                     result = pos->_parent##NameFrom;\
  478.                 }\
  479.                 else /* Right branche and valid left branche */\
  480.                 {\
  481.                     result = pos->_parent##NameFrom->_left##NameFrom;\
  482.                     while (1)\
  483.                     {\
  484.                         while (result->_right##NameFrom)\
  485.                         {\
  486.                             result = result->_right##NameFrom;\
  487.                         }\
  488. \
  489.                         if (result->_left##NameFrom)\
  490.                         {\
  491.                             result = result->_left##NameFrom;\
  492.                         }\
  493.                         else\
  494.                         {\
  495.                             break;\
  496.                         }\
  497.                     }\
  498.                 }\
  499.                 if (result)\
  500.                 {\
  501.                     while (result->_sibling##NameFrom)\
  502.                         result = result->_sibling##NameFrom;\
  503.                 }\
  504.             }\
  505.         }\
  506.     }\
  507. \
  508.     return result;
  509.  
  510. #define METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  511.     assert(this);\
  512.     return _count##NameTo;
  513.  
  514. #ifndef _BODY_VALUETREE_FIND
  515. #define _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  516.     ClassTo* result = 0;\
  517.     if (_first##NameTo)\
  518.     {\
  519.         ClassTo* item = _first##NameTo;\
  520.         unsigned long bit = 0x1;\
  521.         while (1)\
  522.         {\
  523.             if (item->member == value)\
  524.             {\
  525.                 result = item;\
  526.                 break;\
  527.             }\
  528. \
  529.             if ((item->member & bit) == (value & bit))\
  530.             {\
  531.                 if (item->_left##NameFrom)\
  532.                 {\
  533.                     item = item->_left##NameFrom;\
  534.                 }\
  535.                 else\
  536.                 {\
  537.                     break;\
  538.                 }\
  539.             }\
  540.             else\
  541.             {\
  542.                 if (item->_right##NameFrom)\
  543.                 {\
  544.                     item = item->_right##NameFrom;\
  545.                 }\
  546.                 else\
  547.                 {\
  548.                     break;\
  549.                 }\
  550.             }\
  551. \
  552.             bit <<= 1;\
  553.         }\
  554.     }
  555. #endif
  556.  
  557. #define BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  558.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  559.     return result;
  560.  
  561. #define BODY_VALUETREE_FINDREVERSE(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  562.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  563.     if (result)\
  564.     {\
  565.         while (result->_sibling##NameFrom)\
  566.             result = result->_sibling##NameFrom;\
  567.     }\
  568. \
  569.     return result;
  570.  
  571. #define METHODS_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  572.  
  573. #define WRITE_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  574.     rCArchive << Get##NameTo##Count();\
  575.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  576.           rCArchive << item->_index; }
  577.  
  578. #define READ_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  579.     {\
  580.         int count;\
  581.         int index;\
  582. \
  583.         rCArchive >> count;\
  584.         for (int i = 0; i < count; i++)\
  585.         {\
  586.             rCArchive >> index;\
  587.             Add##NameTo((ClassTo*)(pointerArray[index]));\
  588.         }\
  589.     }
  590.  
  591. #endif
  592.